/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections.Generic;
using System.Text;

namespace ELE.EnterpriseLibrary.Data
{
  /// <summary>
  /// Represents a table from the configuration settings.
  /// <para>Lives within a <see cref="ObjectSqlMapping"/></para>
  /// </summary>
  public class ObjectSqlMappingTable : NamedItem, ICloneable
  {
    private Dictionary<string, ObjectPropertySqlBinding> bindings;
    private bool isPrimary = false;
    private string primaryKeyName;
    private string jointColumn;
    private List<string> refBindings;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    public ObjectSqlMappingTable(string name) : base(name) { }

    /// <summary>
    /// Bindings of the table columns.
    /// </summary>
    public ICollection<ObjectPropertySqlBinding> Bindings
    {
      get 
      {
        if (this.bindings != null)
        {
          return bindings.Values;
        }
        return new List<ObjectPropertySqlBinding>();
      }
    }
    /// <summary>
    /// If true specifies this table as being the primary table of the object mapping.
    /// </summary>
    public bool IsPrimary
    {
      get { return isPrimary; }
      set { isPrimary = value; }
    }
    /// <summary>
    /// name of the joint column for referencing binding.
    /// </summary>
    public string JointColumn
    {
      get { return jointColumn; }
      set { jointColumn = value; }
    }
    /// <summary>
    /// Name of primary key binding.
    /// </summary>
    public string PrimaryKey
    {
      get { return primaryKeyName; }
      set { primaryKeyName = value; }
    }
    /// <summary>
    /// Adds a binding to the table.
    /// </summary>
    /// <param name="value"></param>
    public void AddBinding(ObjectPropertySqlBinding value)
    {
      if(value != null)
      {
        if (this.bindings == null)
        {
          this.bindings = new Dictionary<string, ObjectPropertySqlBinding>();
        }
        value.TableName = this.Name;
        if (value.SubQuery != null)
        {
          if (this.refBindings == null)
          {
            this.refBindings = new List<string>();
          }
          this.refBindings.Add(value.Name);
        }
        this.bindings.Add(value.Name, value);
      }
    }
    /// <summary>
    /// Referenced bindings if any.
    /// </summary>
    public List<ObjectPropertySqlBinding> ReferencedBindings
    {
      get
      {
        List<ObjectPropertySqlBinding> referenced = new List<ObjectPropertySqlBinding>();
        if (this.refBindings != null)
        {
          foreach (string bName in this.refBindings)
          {
            referenced.Add(this.GetBinding(bName));
          }
        }
        return referenced;
      }
    }
    /// <summary>
    /// Get a binding by name.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public ObjectPropertySqlBinding GetBinding(string name)
    {
      return this.bindings[name];
    }
    /// <summary>
    /// Check for a binding in the table.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public bool ContainsBinding(string name)
    {
      return this.bindings.ContainsKey(name);
    }
    /// <summary>
    /// Get the primary key binding.
    /// </summary>
    public ObjectPropertySqlBinding PrimaryKeyBinding
    {
      get
      {
        return this.GetBinding(primaryKeyName);
      }
    }
    /// <summary>
    /// If true ignore this binding.
    /// </summary>
    public bool Ignore
    {
      get
      {
        foreach (ObjectPropertySqlBinding binding in this.Bindings)
        {
          if (!binding.Ignore)
          {
            return false;
          }
        }
        return true; ;
      }
    }


    #region ICloneable Members
    /// <summary>
    /// Implementation of <see cref="ICloneable.Clone()"/>
    /// </summary>
    /// <returns></returns>
    public object Clone()
    {
      ObjectSqlMappingTable clone = new ObjectSqlMappingTable(this.Name);
      clone.IsPrimary = this.IsPrimary;
      clone.JointColumn = this.JointColumn;
      clone.PrimaryKey = this.PrimaryKey;
      foreach (ObjectPropertySqlBinding binding in this.Bindings)
      {
        if (!binding.Ignore)
        {
          clone.AddBinding((ObjectPropertySqlBinding)binding.Clone());
        }
      }
      return clone;
    }

    #endregion
  }
}
